package tmp;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.FileVisitResult;
import java.nio.file.FileVisitor;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.nio.file.attribute.BasicFileAttributes;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class DeleteComments {
	public static void main(String[] args) {
		File inDir = new File("F:\\thunder\\book\\Sudoku\\cs2j-trial111209a\\CS2JTranslator\\bin\\in1");
		File outDir = new File("F:\\thunder\\book\\Sudoku\\cs2j-trial111209a\\CS2JTranslator\\bin\\in2");

		DeleteComments d = new DeleteComments();
		try {
			d.start(inDir, outDir);
			System.out.println("done!");
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void start(File inDir, File outDir) throws IOException {
		Files.walkFileTree(inDir.toPath(), new DeleteCommentsVisitor(inDir.toPath(), outDir.toPath()));
	}

	private static final class DeleteCommentsVisitor implements FileVisitor<Path> {
		private final Path source;
		private final Path dest;

		private Logger log = LoggerFactory.getLogger(DeleteCommentsVisitor.class);

		public DeleteCommentsVisitor(Path source, Path dest) {
			this.source = source;
			this.dest = dest;
		}

		private Path getOutputFile(Path inputFile) {
			Path relative = this.source.relativize(inputFile);
			return dest.resolve(relative);
		}

		private void deleteComments(Path in, Path out) throws IOException {
			log.info("processing: [" + in + "] -> [" + out + "]");
			String line = null;
			Charset cs = Charset.forName("ascii");
			try (BufferedReader reader = Files.newBufferedReader(in, cs);
					BufferedWriter writer = Files.newBufferedWriter(out, cs, StandardOpenOption.CREATE,
							StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING)) {
				while (null != (line = reader.readLine())) {
					String bak = line;
					line = line.trim();
					if (line.isEmpty() || line.trim().startsWith("//")) {
						continue;
					} else {
						writer.write(bak);
						if (line.equals("{")) {
						} else {
							writer.newLine();
						}
					}
				}
				writer.flush();
			}
		}

		@Override
		public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
			log.info("entering directory: " + dir);
			return FileVisitResult.CONTINUE;
		}

		@Override
		public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
			if (attrs.isRegularFile() && file.toFile().getName().toLowerCase().endsWith(".cs")) {
				log.info("processing file: " + file);
				Path out = this.getOutputFile(file);
				File outFile = out.toFile().getParentFile();
				if (false == outFile.exists()) {
					outFile.mkdirs();
				}
				this.deleteComments(file, out);
			} else {
				log.info("skip file: " + file);
			}
			return FileVisitResult.CONTINUE;
		}

		@Override
		public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
			log.error("process file failed: " + file, exc);
			return FileVisitResult.CONTINUE;
		}

		@Override
		public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
			log.info("leaving directory: " + dir);
			return FileVisitResult.CONTINUE;
		}

	}
}
